package com.yunchang.springboot.scheduled.keepaLightningDeals;

import com.alibaba.fastjson.JSONArray;
import com.yunchang.springboot.base.BaseService;
import com.yunchang.springboot.mapper.keepaLightningDeals.KeepaLightningDealsDataHandleMapper;
import com.yunchang.springboot.models.DO.KeepaLightningDealsData;
import com.yunchang.springboot.models.DO.KeepaLightningDealsVariationData;
import com.yunchang.springboot.models.DO.SumQuantityDO;
import com.yunchang.springboot.utils.StringUtil;
import com.yunchang.springboot.utils.lightningDeals.KeepaLightningDealsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Update;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class KeepaLightningDealsSchedule extends BaseService {
    @Autowired
    KeepaLightningDealsDataHandleMapper keepaLightningDealsDataHandleMapper;

    /**
     * 根据latest_sum_quantity表中最近一周销量大于等于7的asin去keepa接口获取秒杀数据（如果有的话）
     */
    @Scheduled(cron = "00 53 06 ? * *")
    public void addKeepaLightningDealsData() {
        //先获得所有销量大于等于7的asin集合
        List<SumQuantityDO> asinList = keepaLightningDealsDataHandleMapper.getSumQuantityListGreatThan7();
        String type = "lightningdeal";
        //遍历集合，去调用keepa接口
        Map<String, String> paramsMap = new HashMap<>(2);
        for (SumQuantityDO sumQuantityDO : asinList) {
            String asin = sumQuantityDO.getAsin();
            String area = sumQuantityDO.getAreaCode();
            int domainId = getDomainId(area);
            if (domainId == 0) {
                continue;
            }
            paramsMap.put("domain", String.valueOf(domainId));
            paramsMap.put("asin", asin);
            Map<String, Object> resultMap = KeepaLightningDealsUtil.getClient(type, paramsMap);
            int tokensLeft = Integer.parseInt(StringUtil.valueOf(resultMap.get("tokensLeft")));
            if (tokensLeft <= 5) {
                try {
                    Thread.sleep(60000L);
                } catch (InterruptedException e) {
                    log.error("线程睡眠出错");
                    e.printStackTrace();
                }
            }
            if (null == resultMap.get("lightningDeals")) {
                log.info("该asin：" + asin + "没有参与秒杀活动");
                continue;
            }
            List<Map> data = JSONArray.parseArray(StringUtil.valueOf(resultMap.get("lightningDeals")), Map.class);
            //处理数据
            handleKeepaLightningDealsData(data);
            log.info(asin + "的秒杀数据成功导入");
        }
    }

    /**
     * 处理数据
     * */
    @Transactional(rollbackFor = Exception.class)
    void handleKeepaLightningDealsData(List<Map> data){
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY,1);
        List<Object> keepaLightningDealsDataList = new ArrayList<>();
        List<Object> keepaLightningDealsVariationDataList = new ArrayList<>();
        for (Map map : data) {
            KeepaLightningDealsData keepaLightningDealsData = new KeepaLightningDealsData();
            int domainId = Integer.parseInt(StringUtil.valueOf(map.get("domainId")));
            keepaLightningDealsData.setDomainId(domainId);
            int lastUpdate = Integer.parseInt(StringUtil.valueOf(map.get("lastUpdate")));
            String lastUpdateToDate = LocalDateTime.ofEpochSecond((lastUpdate + 21564000) * 60, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            keepaLightningDealsData.setLastUpdate(lastUpdateToDate);
            String asin = StringUtil.valueOf(map.get("asin"));
            keepaLightningDealsData.setAsin(asin);
            keepaLightningDealsData.setSellerName(StringUtil.valueOf(map.get("sellerName")));
            keepaLightningDealsData.setSellerId(StringUtil.valueOf(map.get("sellerId")));
            String dealId = StringUtil.valueOf(map.get("dealId"));
            keepaLightningDealsData.setDealId(dealId);
            keepaLightningDealsData.setDealPrice(Integer.parseInt(StringUtil.valueOf(map.get("dealPrice"))));
            keepaLightningDealsData.setCurrentPrice(Integer.parseInt(StringUtil.valueOf(map.get("currentPrice"))));
            keepaLightningDealsData.setImage(StringUtil.valueOf(map.get("image")));
            keepaLightningDealsData.setIsPrimeEligible(StringUtil.valueOf(map.get("isPrimeEligible")));
            keepaLightningDealsData.setIsFulfilledByAmazon(StringUtil.valueOf(map.get("isFulfilledByAmazon")));
            keepaLightningDealsData.setIsMap(StringUtil.valueOf(map.get("isMAP")));
            keepaLightningDealsData.setRating(Integer.parseInt(StringUtil.valueOf(map.get("rating"))));
            keepaLightningDealsData.setTotalReviews(Integer.parseInt(StringUtil.valueOf(map.get("totalReviews"))));
            keepaLightningDealsData.setDealState(StringUtil.valueOf(map.get("dealState")));
            int startTime = Integer.parseInt(StringUtil.valueOf(map.get("startTime")));
            String startTimeToDate = LocalDateTime.ofEpochSecond((startTime + 21564000) * 60, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            keepaLightningDealsData.setStartTime(startTimeToDate);
            int endTime = Integer.parseInt(StringUtil.valueOf(map.get("endTime")));
            String endTimeToDate = LocalDateTime.ofEpochSecond((endTime + 21564000) * 60, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            keepaLightningDealsData.setEndTime(endTimeToDate);
            keepaLightningDealsData.setPercentClaimed(Integer.parseInt(StringUtil.valueOf(map.get("percentClaimed"))));
            keepaLightningDealsData.setPercentOff(Integer.parseInt(StringUtil.valueOf(map.get("percentOff"))));
            keepaLightningDealsData.setTitle(StringUtil.valueOf(map.get("title")));
            LocalDateTime lastUpdateTime = LocalDateTime.parse(lastUpdateToDate,df);
            String weekOfYear = "" + lastUpdateTime.getYear() + lastUpdateTime.get(weekFields.weekOfYear());
            keepaLightningDealsData.setWeekOfYear(weekOfYear);
            //判断数据库中是否有该条交易信息，有则更新，无则添加
            KeepaLightningDealsData oneInfo = keepaLightningDealsDataHandleMapper.getInfoByAsinDomainDealId(asin,domainId,dealId);
            if (null == oneInfo){
                keepaLightningDealsDataList.add(keepaLightningDealsData);
            }
            keepaLightningDealsDataHandleMapper.updateInfoByAsinDomainDealId(keepaLightningDealsData);
            //判断是否有variation属性
            if (null == map.get("variation")) {
                continue;
            }
            List<Map> variations = JSONArray.parseArray(StringUtil.valueOf(map.get("variation")), Map.class);
            for (Map variationMap: variations) {
                KeepaLightningDealsVariationData keepaLightningDealsVariationData = new KeepaLightningDealsVariationData();
                keepaLightningDealsVariationData.setAsin(asin);
                keepaLightningDealsVariationData.setDomainId(domainId);
                keepaLightningDealsVariationData.setDealId(dealId);
                keepaLightningDealsVariationData.setDimension(StringUtil.valueOf(variationMap.get("dimension")));
                keepaLightningDealsVariationData.setValue(StringUtil.valueOf(variationMap.get("value")));
                KeepaLightningDealsVariationData oneVariationInfo = keepaLightningDealsDataHandleMapper.getVariationInfoByAsinDomainDealId(asin,domainId,dealId);
                if (null == oneVariationInfo){
                    keepaLightningDealsVariationDataList.add(keepaLightningDealsVariationData);
                }
                keepaLightningDealsDataHandleMapper.updateVariationInfoByAsinDomainDealId(keepaLightningDealsVariationData);
            }
        }
        baseInsertList(keepaLightningDealsDataList);
        baseInsertList(keepaLightningDealsVariationDataList);
    }
    /**
     * 判断区域对应的domainid
     */
    int getDomainId(String area) {
        switch (area) {
            case "US":
                return 1;
            case "GB":
                return 2;
            case "DE":
                return 3;
            case "FR":
                return 4;
            case "JP":
                return 5;
            case "CA":
                return 6;
            case "IT":
                return 8;
            case "ES":
                return 9;
            case "IN":
                return 10;
            default:
                return 0;
        }
    }
}
